package com.neusoft.lohas.modules.ivm.entity.purchase;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.Where;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.Lists;
import com.neusoft.lohas.common.persistence.IdEntity;
import com.neusoft.lohas.common.utils.excel.annotation.ExcelField;
import com.neusoft.lohas.modules.ivm.entity.merchant.Merchant;
import com.neusoft.lohas.modules.ivm.entity.order.Order;
import com.neusoft.lohas.modules.ivm.entity.order.OrderDetail;
import com.neusoft.lohas.modules.ivm.entity.product.Product;
import com.neusoft.lohas.modules.ivm.entity.product.ProductInventoryDetail;

/**
 * 采购详情Entity
 * 
 * @author Jackie.Liu
 * @version 2014-12-29
 */
@Entity
@Table(name = "ivm_purchase_detail")
@DynamicInsert
@DynamicUpdate
public class PurchaseDetail extends IdEntity<PurchaseDetail> {

	private static final long serialVersionUID = 1L;
	private Merchant merchant; // 所属商户
	private Purchase purchase; //对应采购指令
	private int type; //采购清单类型：1为订单采购  2为手动新增采购
	private Product product; // 所属商品
	private double referencePrice; //参考价
	private int buyNumber;
	private int purchaseNumber; //采购总量(可能是多个订单同一个商品合并的总和)
	private int adviceNumber; //建议采购数量
	private int storageNumber; //已入库总量
	private String state; //处理状态：0未完成,1部分完成,2已完成
	private Order order; //分析采购清单时使用
	private List<Order> orderList = Lists.newArrayList(); //所属订单

	public PurchaseDetail() {
		super();
	}

	public PurchaseDetail(String id) {
		this();
		this.id = id;
	}
	
	@ExcelField(title="序号", align=2, sort=15)
	@Transient
	public int getRowNumber(){
		if(purchase == null){
			return 0;
		}
		if (purchase.getDetailList().size()>0) {
			int num=0;
			for (PurchaseDetail detail : purchase.getDetailList()) {
				num++;
				if (detail.getId()==this.getId()) {
					break;
				}
			}
			return num;
		}
		return 0;
	}
	
	@Transient
	public String getMerchantName(){
		return merchant.getName();
	}

	@ManyToOne
	@JoinColumn(name="merchant_id")
	@NotFound(action = NotFoundAction.IGNORE)
	@NotNull(message="归属商户不能为空")
	public Merchant getMerchant() {
		return merchant;
	}

	public void setMerchant(Merchant merchant) {
		this.merchant = merchant;
	}
	
	@Transient
	public String getPurchaseCode(){
		if(purchase==null) return null;
		return purchase.getCode();
	}

	public int getType() {
		return type;
	}

	public void setType(int type) {
		this.type = type;
	}
	
	@ExcelField(title="商品编号", align=2, sort=20)
	@Transient
	public long getProductCode(){
		return product.getCode();
	}
	
	@ExcelField(title="商品名称", align=2, sort=25)
	@Transient
	public String getProductName(){
		return product.getName();
	}

	@ManyToOne
	@JoinColumn(name = "product_id")
	@NotFound(action = NotFoundAction.IGNORE)
	@NotNull(message="所属商品不能为空")
	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}
	
	@Transient
	public int getBuyNumber() {
		return buyNumber;
	}

	public void setBuyNumber(int buyNumber) {
		this.buyNumber = buyNumber;
	}

	//@ExcelField(title="采购数", align=2, sort=30)
	public int getPurchaseNumber() {
		return purchaseNumber;
	}

	public void setPurchaseNumber(int purchaseNumber) {
		this.purchaseNumber = purchaseNumber;
	}
	
	public int getAdviceNumber() {
		if(adviceNumber==0){
			return this.purchaseNumber;
		}
		return adviceNumber;
	}

	public void setAdviceNumber(int adviceNumber) {
		this.adviceNumber = adviceNumber;
	}

	@ExcelField(title="采购说明", align=2, sort=30)
	@Transient
	public String getProductAssisTitle(){
		return product.getPurchaseDesc();
	}
	
	@ExcelField(title="计划采购量", align=2, sort=35)
	@Transient
	public String getPurchaseNumberPlay() {
		return purchaseNumber+product.getSpecUnit().getName();
	}
	
	@ExcelField(title="建议采购量", align=2, sort=40)
	@Transient
	public String getAdviceNum() {
		return adviceNumber+product.getSpecUnit().getName();
	}
	
	//@ExcelField(title="来源", align=2, sort=40)
	@Transient
	public String getTypeStr(){
		if(type==1) return "订单";
		else return "手动";
	}
	
	//@ExcelField(title="状态", align=2, sort=45)
	@Transient
	public String getStateStr(){
		if(type==0) return "采购中";
		else return "已完成";
	}
	
	@ExcelField(title="实际采购量", align=2, sort=45)
	@Transient
	public String getRealNumber(){
		return "";
	}
	
	//@ExcelField(title="采购偏差比", align=2, sort=50)
	@Transient
	public String getBuyNumRate(){
		return "";
	}
	
	@ExcelField(title="采购金额", align=2, sort=55)
	@Transient
	public String getBuyNumTotal(){
		return "";
	}
	
	@ExcelField(title="单价", align=2, sort=60)
	@Transient
	public String getBuyNumPrice(){
		return "";
	}
	
	public double getReferencePrice() {
		return referencePrice;
	}

	public void setReferencePrice(double referencePrice) {
		this.referencePrice = referencePrice;
	}
	
	@Transient
	public int getStorageNumber() {
		int storageNumber = 0;
		if(product != null && product.getInventoryDetailList().size()>0){
			List<ProductInventoryDetail> inventoryDetailList = product.getInventoryDetailList();
			for(ProductInventoryDetail inventoryDetail: inventoryDetailList){
				if(this.purchase != null && inventoryDetail.getPurchase()!=null && inventoryDetail.getPurchase().getId().equals(this.purchase.getId())){
					storageNumber += inventoryDetail.getWinWeight();
				}
			}
		}
		return storageNumber;
	}
	
	//采购总金额
	@Transient
	public double getTotalAmount() {
		double amount = 0;
		if(product != null && product.getInventoryDetailList().size()>0){
			List<ProductInventoryDetail> inventoryDetailList = product.getInventoryDetailList();
			for(ProductInventoryDetail inventoryDetail: inventoryDetailList){
				if(this.purchase != null && inventoryDetail.getPurchase()!=null && inventoryDetail.getPurchase().getId().equals(this.purchase.getId())){
					amount += inventoryDetail.getAmount();
				}
			}
		}
		return amount;
	}
	
	//入库记录ID
	@Transient
	public String getInventoryId() {
		if(product != null && product.getInventoryDetailList().size()>0){
			List<ProductInventoryDetail> inventoryDetailList = product.getInventoryDetailList();
			for(ProductInventoryDetail inventoryDetail: inventoryDetailList){
				if(this.purchase != null && inventoryDetail.getPurchase()!=null && inventoryDetail.getPurchase().getId().equals(this.purchase.getId())){
					return inventoryDetail.getId();
				}
			}
		}
		return "";
	}
	
	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public void setStorageNumber(int storageNumber) {
		this.storageNumber = storageNumber;
	}

	@ManyToOne
	@JoinColumn(name="purchase_id")
	@NotFound(action = NotFoundAction.IGNORE)
	public Purchase getPurchase() {
		return purchase;
	}

	public void setPurchase(Purchase purchase) {
		this.purchase = purchase;
	}
	
	@Transient
	public Order getOrder() {
		return order;
	}

	public void setOrder(Order order) {
		this.order = order;
	}

	@ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
	@JoinTable(name = "ivm_purchase_detail_order", joinColumns = { @JoinColumn(name = "purchase_detail_id") }, inverseJoinColumns = { @JoinColumn(name = "order_id") })
	@Where(clause="del_flag='"+DEL_FLAG_NORMAL+"'")
	@OrderBy("id") @Fetch(FetchMode.SUBSELECT)
	@NotFound(action = NotFoundAction.IGNORE)
	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	@JsonIgnore
	public List<Order> getOrderList() {
		return orderList;
	}

	public void setOrderList(List<Order> orderList) {
		this.orderList = orderList;
	}

	/**
	 * 对应采购清单主表对应订单中该商品的详情列表信息(注意只有订单匹配出来的采购清单有对应数据，手动添加的采购没有数据)
	 * @return
	 */
	@Transient
	public List<OrderDetail> getOrderDetailList() {
		List<OrderDetail> result = Lists.newArrayList();
		if (this.getOrderList().size()>0) {
			for (Order order : this.getOrderList()) {
				for (OrderDetail orderDetail : order.getDetailList()) {
					if (orderDetail.getProduct().getId().equals(this.product.getId())) {
						result.add(orderDetail);
					}
				}
			}
		}
		return result;
	}

}
